﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SCEM.DTO;
using SCEM.External;
using SCEM.DataLayer;
using SCEM.CompraProdutos;

namespace SCEM.CompraEquipamentos
{
    /// <summary>
    /// Gerenciador de compra de equipamentos.
    /// </summary>
    public class GerenciadorCompraEquipamento
    {
        /// <summary>
        /// Cria uma nova ordem de compra de equipamento e a salva se for aprovada pelo financeiro
        /// </summary>
        /// <param name="dto">O DTO da ordem de compra a ser criada</param>
        /// <param name="equipamentoDTO">O DTO do equipamento já salvo</param>
        /// <returns>o DTO salvo ou <code>null</code> em caso de erro ou não aprovação do financeiro</returns>
        public OrdemCompraEquipamentoDTO CreateOrdemCompraEquipamento(OrdemCompraEquipamentoDTO dto, EquipamentoDTO equipamentoDTO)
        {
            using (var context = new SCEMContainer())
            {
                if (dto == null)
                    return null;

                OrdemCompraEquipamento ordemTeste = dto.ConvertToEntity(context);
                Equipamento equipamentoTeste = equipamentoDTO.ConvertToEntity(context);
                if (ordemTeste == null || equipamentoTeste == null)
                    return null;
            }

            // Verifica a autorização para o financeiro
            dto.AutorizacaoFinanceiro = ExternalServiceRequestDispatcher.Instance.DispararNovaOrdemCompraEquipamento(dto.EquipamentoId, dto.Preco);
            if (String.IsNullOrEmpty(dto.AutorizacaoFinanceiro))
                return null;

            // Se autorizado salva o equipamento
            EquipamentoDAO equipamentoDAO = new EquipamentoDAO();
            equipamentoDTO.Ativo = false; // Mantém falso até o status da OCE ser alterada
            equipamentoDTO.DataCompra = DateTime.Now;
            EquipamentoDTO equipamentoDTOSave = (EquipamentoDTO)equipamentoDAO.Save(equipamentoDTO);
            if (equipamentoDTOSave == null)
            {
                // Ocorreu algum erro no cadastro do equipamento - A ordem deve ser cancelada
                ExternalServiceRequestDispatcher.Instance.CancelarOrdemCompraEquipamento(dto.AutorizacaoFinanceiro);
                return null;
            }

            // Associa-se a OCE com o novo equipamento
            dto.EquipamentoId = equipamentoDTOSave.Id;
            // Salva a ordem de compra
            OrdemCompraEquipamentoDAO dao = new OrdemCompraEquipamentoDAO();
            OrdemCompraEquipamentoDTO dtoSave = (OrdemCompraEquipamentoDTO)dao.Save(dto);

            // Verifica se a ordem foi salva corretamente, caso contrário cancela-se a OCE
            if (dtoSave == null)
                ExternalServiceRequestDispatcher.Instance.CancelarOrdemCompraEquipamento(dto.AutorizacaoFinanceiro);

            return dtoSave;
        }

        /// <summary>
        /// Atualiza o status da ordem de compra de equipamento retornando <code>true</code>
        /// caso bem sucedido ou <code>false</code> caso contrário
        /// </summary>
        /// <param name="idOrdemCompraEquipamento">id da ordem de compra do  equipamento</param>
        /// <param name="novoStatus">novo status</param>
        /// <returns>Boolean indicando o sucesso da operação</returns>
        public bool UpdateOrdemCompraEquipamentoStatus(string idOrdemCompraEquipamento, StatusOrdemCompra novoStatus)
        {
            OrdemCompraEquipamentoDAO dao = new OrdemCompraEquipamentoDAO();
            OrdemCompraEquipamentoDTO dto = (OrdemCompraEquipamentoDTO)dao.Get(idOrdemCompraEquipamento);
            if (dto == null) // OCE inexistente
                return false;

            if (dto.Status == StatusOrdemCompra.CANCELADO || dto.Status == StatusOrdemCompra.FINALIZADO)
                return (novoStatus == dto.Status);

            if (novoStatus == StatusOrdemCompra.CANCELADO)
            {
                ExternalServiceRequestDispatcher.Instance.CancelarOrdemCompraEquipamento(dto.AutorizacaoFinanceiro);
            }
            else if (novoStatus == StatusOrdemCompra.FINALIZADO)
            {
                // Atualiza o equipamento para se tornar ativo
                if (!String.IsNullOrEmpty(dto.EquipamentoId))
                {
                    EquipamentoDAO equipamentoDAO = new EquipamentoDAO();
                    EquipamentoDTO equipamentoDTO = (EquipamentoDTO)equipamentoDAO.Get(dto.EquipamentoId);
                    equipamentoDTO.Ativo = true;
                    equipamentoDTO.DataCompra = DateTime.Now;
                    EquipamentoDTO equipamentoDTOSave = (EquipamentoDTO)equipamentoDAO.Update(equipamentoDTO);

                    // Verifica se ocorreu alguma erro e não atualiza status em caso positivo
                    if (equipamentoDTOSave == null)
                        return false;
                }
            }

            // Finalmente atualiza a ordem de compra
            dto.Status = novoStatus;
            return (dao.Update(dto) != null);
        }
    }
}
